﻿using Ross.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Security;

namespace Ross.Traning
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
    public class SimpleAuthenticationFilter: AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
            {
                return;
            }
            var authValue = actionContext.Request.Headers.Authorization;
            if (authValue == null)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.Unauthorized, new HttpError("Unauthorized access!"));
            }
            else
            {                
                string authParameter = authValue.Parameter;
                if (string.IsNullOrEmpty(authParameter))
                    actionContext.Response = actionContext.Request.CreateErrorResponse(
                        HttpStatusCode.Unauthorized, new HttpError("Incorrect authorization information!"));
                else
                {
                    var strTicket = FormsAuthentication.Decrypt(authParameter).UserData;
                    var index = strTicket.IndexOf("&");
                    string username = strTicket.Substring(0, index);
                    string password = strTicket.Substring(index + 1);
                    BasicAuthenticationIdentity userIdentity = new BasicAuthenticationIdentity(username, password);
                    HttpContext.Current.User = new GenericPrincipal(userIdentity, null);

                    //解密用户ticket,并校验用户名密码是否匹配
                    if (!ValidateTicket(username,password))
                    {
                        actionContext.Response = actionContext.Request.CreateErrorResponse(
                        HttpStatusCode.Unauthorized, new HttpError("The authorization is wrong, please try again!"));
                    }
                    else
                        Thread.CurrentPrincipal = HttpContext.Current.User;
                }
                
            }
        }

        private bool ValidateTicket(string username,string password)
        {
            try
            {
                if (HttpContext.Current.User == null || string.IsNullOrEmpty(HttpContext.Current.User.Identity.Name))
                {                    
                    using (UserService serv = new UserService(Controllers.BaseApiController.dbContextStr))
                    {
                        return serv.ValidateUser(username, password);
                    }
                }
                else
                    return true;
            }
            catch
            {
                return false;
            }
        }
    }
}